package c15;

import java.util.ArrayDeque;
import java.util.Queue;

public class ProducorConsumerDemo {
    public static void main(String[] args) {
        MyBlockingQueue<String> queue = new MyBlockingQueue<>(10);
        new Producer(queue).start();
        new Consumer(queue).start();
    }

    static class MyBlockingQueue<E> {
        private int limit;
        private Queue<E> queue = null;

        public MyBlockingQueue(int limit) {
            this.limit = limit;
            queue = new ArrayDeque<E>();
        }

        public synchronized void put(E e) {
            if (queue.size() == limit) {
                try {
                    wait();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
            queue.add(e);
            notifyAll();
        }

        public synchronized E take() {
            if (queue.isEmpty()) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            E e = queue.poll();
            notifyAll();
            return e;
        }
    }

    // 简单的生产者
    static class Producer extends Thread {
        MyBlockingQueue<String> queue;

        public Producer(MyBlockingQueue<String> queue) {
            this.queue = queue;
        }

        @Override
        public void run() {
            int num = 0;
            while (true) {
                String s = String.valueOf(num);
                queue.put(s);
                System.out.println("produce task:" + s);
                num++;
                try {
                    Thread.sleep((int)Math.random()*10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 简单的消费者
    static class Consumer extends Thread {
        MyBlockingQueue<String> queue;

        public Consumer(MyBlockingQueue<String> queue) {
            this.queue = queue;
        }

        @Override
        public void run() {
            while (true) {
                String take = queue.take();
                System.out.println("Consumer handle task:" + take);
                try {
                    Thread.sleep((int)Math.random()*10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}


